CORE(5) | Linux Programmer's Manual | CORE(5) |
名前¶
core - コアダンプファイル
説明¶
ある種のシグナルを受けた場合のデフォルトのアクションは、 プロセスを終了し (terminate)、 コアダンプファイル (core dump file) を生成することである。コアダンプファイルは、ディスク上に生成される 終了時のプロセスのメモリイメージを内容とするファイルである。 このイメージをデバッガ (例えば gdb(1)) に読み込んで、 プログラムが終了した時点のプログラムの状態を検査することができる。 どのシグナルを受けたときにプロセスがコアダンプを生成するかのリストは signal(7) に書かれている。
プロセスはソフト・リソース制限 RLIMIT_CORE を設定することで、「コアダンプ」シグナルを受信した際に生成される コアダンプファイルのサイズに上限を課すことができる。詳細は getrlimit(2) を参照。
コアダンプファイルが生成されない状況がいくつかある:
- プロセスがコアファイルを書き込む許可を持たない場合 (デフォルトでは、コアファイルは core という名前で、カレント・ワーキング・ディレクトリに生成される。 命名規則の詳細は下記を参照)。 コアファイルを生成しようとしたディレクトリが書き込み可能でない場合、 もしくは同じ名前のファイルが存在し、そのファイルが書き込み可能でも 通常のファイルでもない場合 (例えば、ディレクトリやシンボリックリンク)、 コアファイルの生成は失敗する。
- コアダンプに使おうとしたのと同じ名前の (書き込み可能な、通常の) ファイルが すでに存在し、そのファイルに対するハードリンクが 2個以上ある場合。
- コアダンプファイルを生成しようとしたファイルシステムがフルであるか、 inode が全て使用されているか、読み込み専用でマウントされている場合。 または、そのユーザのディスク使用量がそのファイルシステムの クオータ (quota) に達している。
- コアダンプファイルを生成しようとしたディレクトリが存在しない場合。
- プロセス毎のリソース制限 RLIMIT_CORE (コアファイルのサイズ) か RLIMIT_FSIZE (ファイルサイズ) が 0 に設定されている場合。 getrlimit(2) やシェルの ulimit コマンドのドキュメント (csh(1) の limit) を参照。
- プロセスが実行したバイナリファイルの読み出し許可が有効になっていない場合。
- プロセスが実行している set-user-ID (set-group-ID) プログラムの所有者の ユーザ (グループ) が、プロセスの実 UID (実 GID) と異なる場合 (但し、 prctl(2) PR_SET_DUMPABLE 操作の説明と、 proc(5) の /proc/sys/fs/suid_dumpable ファイルの説明も参照のこと)。
コアダンプファイルの名前¶
デフォルトでは、コアダンプファイルの名前は core となるが、コアダンプファイルの名前を決めるのに使われるテンプレートを /proc/sys/kernel/core_pattern ファイルに定義することで、ファイル名を変更することができる (/proc/sys/kernel/core_pattern は Linux 2.6 および 2.4.21 以降で利用できる)。 テンプレートには % 指示子 (specifier) を入れることができる。 これはコアファイルが生成される際に、以下の値に置き換えられる。
- %%
- 1 つの % 文字
- %p
- ダンプされたプロセスのプロセスID (PID)
- %u
- ダンプされたプロセスの実ユーザ ID (real UID)
- %g
- ダンプされたプロセスの実グループ ID (real GID)
- %s
- ダンプを引き起こしたシグナルの番号
- %t
- ダンプ時刻 (紀元 (1970 年 1 月 1 日 0:00) からの秒数で表現される)
- %h
- ホスト名 (uname(2) で返される nodename と同じ)
- %e
- 実行ファイル名 (パス名のプレフィックスは含まれない)
- %c
- クラッシュしたプロセスのコアファイルのサイズに関するソフトリソース上限 (Linux 2.6.24 以降)
テンプレートの末尾に 1 個だけ % がある場合、 その % はコアファイル名には含められない。また、上で列挙されて いない % と文字の組み合わせがあった場合も同様である。 テンプレートにおける他の文字は、 コアファイル名としてそのまま使われる。 テンプレートには '/' 文字を入れることができ、 ディレクトリ名の区切り文字と解釈される。 結果として生成されるコアファイル名の最大サイズは 128 バイトである (2.6.19 より前のカーネルでは 64 バイト)。 このファイルのデフォルト値は "core" である。 以前のものとの互換性のため、 /proc/sys/kernel/core_pattern に "%p" が含まれず、 かつ /proc/sys/kernel/core_uses_pid (下記参照) が 0 でない場合は、.PID がコアファイル名に追加される。
バージョン 2.4 以降の Linux では コアダンプファイルの名前を制御する原始的な方法も提供されている。 /proc/sys/kernel/core_uses_pid ファイルに値 0 が書かれている場合、コアダンプファイルは単純に core という名前になる。このファイルに 0 以外の値が書かれている場合、 コアダンプファイルは core.PID という形式の名前になり、ファイル名にプロセス ID が含まれる。
コアダンプのプログラムへのパイプ¶
カーネル 2.6.19 以降では、Linux は /proc/sys/kernel/core_pattern ファイルの別の構文をサポートしている。 このファイルの最初の文字がパイプ記号 (|) であれば、 その行の残りの部分は実行するプログラムとして解釈される。 コアダンプは、ディスク上のファイルに書き込まれるのではなく、 プログラムの標準入力として渡される。 以下の点に注意すること。
- プログラムは絶対パス名 (もしくはルートディレクトリ / からの 相対パス名) で指定されなければならない。 また、'|' 文字の直後から始めなければならない。
- プログラムを実行するために生成されるプロセスは、 ユーザ、グループとも root として実行される。
- コマンドライン引き数をプログラムに与えることができ (カーネル 2.6.24 以降)、 引き数はホワイトスペースで区切る (1行の最大長は 128 バイトが上限である)。
- コマンドライン引き数には、上記のリストにある % 指示子を含めることができる。 例えば、ダンプされるプロセスの PID を渡すには、 引き数に %p を指定する。
どのマッピングをコアダンプに書き込むかを制御する¶
カーネル 2.6.23 以降では、Linux 固有のファイル /proc/PID/coredump_filter を使って、対応するプロセス ID を持つプロセスに対してコアダンプが行われる 際に、どのメモリセグメントをコアダンプファイルに書き込むかを制御できる。
このファイルの値はメモリマッピング種別 (mmap(2) 参照) のビットマスクである。 マスク内のあるビットがセットされると、そのビットに対応する種別の メモリマッピングがダンプされる。セットされていないものはダンプされない。 このファイルの各ビットは以下の意味を持つ。
coredump_filter のデフォルト値は 0x3 である。 この値は昔からの Linux の挙動を反映したものであり、 無名メモリセグメント (anonymous memory segments) だけがダンプされる ことを意味する。
coredump_filter の値に関わらず、フレームバッファなどの memory-mapped I/O に関する ページは決してダンプされず、仮想 DSO ページは常にダンプされる。
fork(2) で作成される子プロセスは親プロセスの coredump_filter の値を継承する。 execve(2) の前後で coredump_filter の値は保持される。
例のように、プログラムを実行する前に親シェルの coredump_filter を設定しておくと役立つことがある。
$ echo 0x7 > /proc/self/coredump_filter $ ./some_program
このファイルが提供されるのは、カーネルが設定オプション CONFIG_ELF_CORE を有効にして作成された場合だけである。
備考¶
gdb(1) の gcore コマンドを使用すると、実行中のプロセスのコアダンプを取得できる。
マルチスレッドプロセス (より正確には、 clone(2) の CLONE_VM で生成された別プロセスとメモリを共有しているプロセス) がコアダンプを生成する場合、 コアファイル名にプロセス ID が必ず付加される。 ただし、 /proc/sys/kernel/core_pattern の %p 指定によりコアファイル名のどこか他の場所にプロセス ID が すでに含まれている場合は、プロセス ID が末尾に付加されない。 (この機能がまず役に立つのは LinuxThreads 実装を利用している場合である。 LinuxThreads 実装では、プロセス内の個々のスレッドは異なるプロセス ID を持つ。)
例¶
以下のプログラムは /proc/sys/kernel/core_pattern ファイルのパイプ構文の使用例を示している。 以下のシェルのセッションはこのプログラムの使用例を示すものである (コンパイルして core_pattern_pipe_test という名前の実行ファイルを作成している)。
$ cc -o core_pattern_pipe_test core_pattern_pipe_test.c $ su Password: # echo '|$PWD/core_pattern_pipe_test %p UID=%u GID=%g sig=%s' > \ /proc/sys/kernel/core_pattern # exit $ sleep 100 ^\ # type control-backslash Quit (core dumped) $ cat core.info argc=5 argc[0]=</home/mtk/core_pattern_pipe_test> argc[1]=<20575> argc[2]=<UID=1000> argc[3]=<GID=100> argc[4]=<sig=3> Total bytes in core dump: 282624
プログラムのソース¶
/* core_pattern_pipe_test.c */ #define _GNU_SOURCE #include <sys/stat.h> #include <fcntl.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define BUF_SIZE 1024 int main(int argc, char *argv[]) {
int tot, j;
ssize_t nread;
char buf[BUF_SIZE];
FILE *fp;
char cwd[PATH_MAX];
/* Change our current working directory to that of the
crashing process */
snprintf(cwd, PATH_MAX, "/proc/%s/cwd", argv[1]);
chdir(cwd);
/* Write output to file "core.info" in that directory */
fp = fopen("core.info", "w+");
if (fp == NULL)
exit(EXIT_FAILURE);
/* Display command-line arguments given to core_pattern
pipe program */
fprintf(fp, "argc=%d\n", argc);
for (j = 0; j < argc; j++)
fprintf(fp, "argc[%d]=<%s>\n", j, argv[j]);
/* Count bytes in standard input (the core dump) */
tot = 0;
while ((nread = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)
tot += nread;
fprintf(fp, "Total bytes in core dump: %d\n", tot);
exit(EXIT_SUCCESS); }
関連項目¶
bash(1), gdb(1), getrlimit(2), mmap(2), prctl(2), sigaction(2), elf(5), proc(5), pthreads(7), signal(7)
2008-08-26 | Linux |